package com.ophiux.authservice.service;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.ophiux.authservice.model.OphiuxUser;
import com.ophiux.common.core.base.Result;
import com.ophiux.common.core.constant.CommonConstants;
import com.ophiux.common.core.constant.SecurityConstants;
import com.ophiux.system.api.feign.RemoteUserService;
import com.ophiux.system.model.dto.UserInfo;
import com.ophiux.system.model.entity.SysUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Primary;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * @desc: 用户详细信息
 * @author: hhl
 * @date：2022/7/28 10:31
 */
@Slf4j
@Primary
@RequiredArgsConstructor
@Service
public class OphiuxUserDetailsServiceImpl implements UserDetailsService {

	private final RemoteUserService remoteUserService;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		//TODO 可以做redis缓存
		Result<UserInfo> result = remoteUserService.info(username, SecurityConstants.FROM_IN);
		UserDetails userDetails = getUserDetails(result);
		return userDetails;
	}


	/**
	 * 构建userdetails
	 * @param result 用户信息
	 * @return
	 */
	private UserDetails getUserDetails(Result<UserInfo> result) {
		if (result == null || result.getData() == null) {
			throw new UsernameNotFoundException("用户不存在");
		}

		UserInfo info = result.getData();
		Set<String> dbAuthsSet = new HashSet<>();
		if (ArrayUtil.isNotEmpty(info.getRoles())) {
			// 获取角色
			Arrays.stream(info.getRoles()).forEach(roleId -> dbAuthsSet.add(SecurityConstants.ROLE + roleId));
			// 获取资源
			dbAuthsSet.addAll(Arrays.asList(info.getPermissions()));
		}
		Collection<? extends GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(dbAuthsSet.toArray(new String[0]));
		SysUser user = info.getSysUser();
		boolean enabled = StrUtil.equals(user.getLockFlag(),  CommonConstants.STATUS_NORMAL);
		// 构造security用户   (密码数据库没有存{bcrypt}，这里要加上)
		return new OphiuxUser(user.getUserId(), user.getUsername(), user.getDeptId(), user.getPhone(), user.getAvatar(),
				user.getNickname(), user.getName(), user.getEmail(), user.getTenantId(),
				SecurityConstants.BCRYPT + user.getPassword(), true, true, "1", true,
				!CommonConstants.STATUS_LOCK.equals(user.getLockFlag()), authorities);
	}
}
